const { think } = require('thinkjs');
const Base = require('./base.js');
const { default: BigNumber } = require('bignumber.js');

module.exports = class extends Base {
  async listAcAction() {
    // 一次性查询所有设备
    const allDevices = await this.model('equipment_list')
      .order(['id DESC'])
      .where({ project_id: this.get('project_id') })
      .select();

    // 筛选出父级设备
    const parentDevices = allDevices.filter((device) => device.type === 1);

    // 为每个父级设备添加子设备
    for (const parent of parentDevices) {
      parent.children = allDevices.filter(
        (device) => device.parent_id === parent.id
      );
    }

    return this.success(parentDevices);
  }

  async putAcAction() {
    const values = this.post();
    const method = this.post('method');
    const model = this.model('equipment_list');

    if (method === 'edit') {
      await model.where({ id: this.post('id') }).update({
        name: values.name,
        ac_type: values.ac_type,
      });
    } else if (method === 'create') {
      delete values.id;
      const addId = await model.add(values);
    }
    return this.success(values);
  }

  async listDataAction() {
    const id = this.get('ac_id');
    const page = this.get('page') || 1;
    const size = this.get('size') || 20;

    const data = await this.model('ac_list')
      .where({ ac_id: id })
      .order(['update_time DESC'])
      .page(page, size)
      .countSelect();

    return this.success(data);
  }

  async listAllAction() {
    const data = await this.model('equipment_list').select();

    return this.success(data);
  }

  async putAction() {
    const values = this.post();
    const id = this.post('id');
    const model = this.model('ac_list');

    if (id > 0) {
      await model.where({ id: id }).update(values);
      this.model('addLog').add({
        user_id: this.getLoginUserId(),
        title: '编辑ac读数',
        content: id,
      });
    } else {
      delete values.id;
      const addId = await model.add(values);
      this.model('addLog').add({
        user_id: this.getLoginUserId(),
        title: '新增AC读数',
        content: addId,
      });
    }
    return this.success(values);
  }

  async delAction() {
    const id = this.get('id');
    const d = await this.model('ac_list')
      .where({ id: id })
      .find();

    await this.model('ac_list')
      .where({ id: id })
      .delete();

    this.model('addLog').add({
      user_id: this.getLoginUserId(),
      title: '删除读数',
      content: JSON.stringify(d),
    });

    return this.success();
  }
  async delAcAction() {
    const id = this.get('id');
    const has = await this.model('equipment_list')
      .where({ parent_id: id })
      .find();
    if (!think.isEmpty(has)) {
      return this.fail(400, '不能直接删除父级设备');
    }
    await this.model('equipment_list')
      .where({ id: id })
      .delete();

    return this.success();
  }

  async createBillAction() {
    const id = this.get('id');
    const currentData = await this.model('ac_list')
      .alias('a')
      .join({
        equipment_list: {
          join: 'left',
          as: 'e',
          on: ['ac_id', 'id'],
        },
      })
      .where({ 'a.id': id })
      .field(
        'a.*, e.contract_id, e.type, e.parent_id, e.name as ac_name, e.ac_type'
      )
      .find();
    if (think.isEmpty(currentData.contract_id)) {
      return this.fail(400, '改设备还未绑定合同');
    }

    const preData = await this.model('ac_list')
      .where({
        update_time: ['<', currentData.update_time],
        ac_id: currentData.ac_id,
      })
      .order(['update_time DESC'])
      .find();

    if (think.isEmpty(preData)) {
      return this.fail(400, '没有更早的读数');
    }

    if (currentData.num < preData.num) {
      return this.fail(400, '读数为负,请检查');
    }

    if (currentData.type === 2) {
      const p_list_ids = await this.model('equipment_list')
        .where({
          parent_id: currentData.parent_id,
          id: currentData.parent_id,
          _logic: 'OR',
        })
        .field('id, type, contract_id, name, ac_type')
        .select();
      let dividend = 0;
      let divisor = 0;

      for (const item of p_list_ids) {
        const hasData = await this.model('ac_list')
          .where({ update_time: currentData.update_time, ac_id: item.id })
          .find();
        if (think.isEmpty(hasData)) {
          return this.fail(
            400,
            '此设备为分机,请确保其他分机和主机有当前记录日期的读数'
          );
        }
        const hasPreData = await this.model('ac_list')
          .where({
            update_time: ['<', hasData.update_time],
            ac_id: item.id,
          })
          .order(['update_time DESC'])
          .find();

        if (think.isEmpty(hasPreData)) {
          return this.fail(400, '此设备为分机,请确保其他分机和主机有更早读数');
        }

        item.num_left = BigNumber(hasData.num)
          .minus(BigNumber(hasPreData.num))
          .toFixed();

        if (item.type === 2) {
          dividend = BigNumber(dividend)
            .plus(BigNumber(item.num_left))
            .toFixed();
        } else if (item.type === 1) {
          divisor = item.num_left;
        }
        item.preData = hasPreData;
        item.currentData = hasData;
      }

      for (const item of p_list_ids) {
        if (item.type === 2) {
          item.real_num = BigNumber(divisor)
            .div(BigNumber(dividend))
            .times(item.num_left)
            .toFixed(2);

          if (item.contract_id) {
            await this.model('ac_list')
              .where({
                id: item.currentData.id,
              })
              .update({
                status: 1,
                num_fen: BigNumber(item.preData.num_fen)
                  .plus(BigNumber(item.real_num))
                  .toFixed(),
              });

            const info = {
              current: BigNumber(item.preData.num_fen)
                .plus(item.real_num)
                .toFixed(),
              prev: item.preData.num_fen,
              ac_id: item.id,
              ac_name: item.name,
            };

            await this.model('income_list').add({
              // month: JSON.stringify([
              //   item.preData.update_time,
              //   item.currentData.update_time,
              // ]),
              shuidian_info: JSON.stringify(info),
              type: 'shuidian',
              contract_id: item.contract_id,
              create_time: ['exp', 'CURRENT_TIMESTAMP()'],
              circle_start: item.preData.update_time,
              circle_end: item.currentData.update_time,
              status: 0,
              shuidian_type: item.ac_type,
              shuidian_num: item.real_num,
              remark: '设备读数自动生成账单(分表)',
            });
          }
        }
      }
      return this.success(p_list_ids);
    } else {
      const hasChild = await this.model('equipment_list')
        .where({ parent_id: currentData.ac_id })
        .find();
      if (!think.isEmpty(hasChild)) {
        return this.fail(400, '此设备为外机,如需生成读数,请移步内机生成');
      }
      if (currentData.contract_id) {
        await this.model('ac_list')
          .where({
            id: id,
          })
          .update({ status: 1 });
        const info = {
          current: currentData.num,
          prev: preData.num,
          ac_id: id,
          ac_name: currentData.ac_name,
        };
        await this.model('income_list').add({
          type: 'shuidian',
          contract_id: currentData.contract_id,
          create_time: ['exp', 'CURRENT_TIMESTAMP()'],
          circle_start: preData.update_time,
          circle_end: currentData.update_time,
          shuidian_type: currentData.ac_type,
          status: 0,
          shuidian_info: JSON.stringify(info),
          shuidian_num: BigNumber(currentData.num)
            .minus(BigNumber(preData.num))
            .toFixed(),
          remark: '设备读数自动生成账单(主表)',
        });
      }

      return this.success();
    }
  }
};
